#ifndef AUDIODEVICES_H
#define AUDIODEVICES_H

#include <QAudioDevice>
#include <QMediaDevices>
#include <QObject>
#include <QWidget>
#include <QMediaDevices>
//#include <QMediaFormat>
#include <QComboBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QGridLayout>
#include <QGroupBox>
#include <QFormLayout>
#include <QIODevice>


#include <QIODevice>
#include <QList>
#include <QPointF>
// #include <QXYSeries>

#include <QThread>

QT_FORWARD_DECLARE_CLASS(QXYSeries)

class AudioDeviceIO : public QIODevice
{
    Q_OBJECT
public:
    explicit AudioDeviceIO(QXYSeries *series,QObject *parent = nullptr):
            QIODevice(parent),
            m_series(series)
    {
        m_buffer.reserve(sampleCount);
        for (int i = 0; i < sampleCount; ++i)
            m_buffer.append(QPointF(i, 0));
        ::memset(m_sample_buffer,0,sizeof(m_sample_buffer));
    }

    static const int sampleCount = 8000;

protected:
    qint64 readData(char *data, qint64 maxSize) override
    {
        Q_UNUSED(data);
        Q_UNUSED(maxSize);
        return -1;
    }
    qint64 writeData(const char *data, qint64 maxSize) override
    {
        static const int resolution = 4;

//        qDebug() << "wd:" << maxSize;

        int start = 0;
        const int availableSamples = int(maxSize) / resolution;
        if (availableSamples < sampleCount) {
            start = sampleCount - availableSamples;
            ::memcpy((void *)&m_sample_buffer[0],(void *)&m_sample_buffer[availableSamples],start * resolution);
        }
        ::memcpy(&m_sample_buffer[start],data,(sampleCount - start) * resolution);
        for (int i = 0; i < sampleCount; ++i)
            m_buffer[i].setY(m_sample_buffer[i]);
        // m_series->replace(m_buffer);
        return (sampleCount - start) * resolution;
    }

private:
    QList<QPointF> m_buffer;
    QXYSeries *m_series = nullptr;
    float m_sample_buffer[sampleCount];
};


class AudioDevice : public QWidget
{
    Q_OBJECT

public:
    explicit AudioDevice(QWidget *parent = nullptr);
    ~AudioDevice();

    QAudioDevice get_input_device(void);
    QAudioDevice get_output_device(void);
private:
//    QAudioDevice m_deviceInfo;
    //QAudioDevice::Mode m_mode = QAudioDevice::Input;
    QMediaDevices *m_devices = nullptr;
    //input
    QComboBox *cmbInputDevice;
    QComboBox *cmbInputDeviceSampleRate;
    QComboBox *cmbInputDeviceChannel;
    QComboBox *cmbInputDeviceFormat;
//    QLabel *labInputDevice;
//    QLabel *labInputDeviceSampleRate;
//    QLabel *labInputDeviceChannel;
//    QLabel *labInputDeviceFormat;
    QGroupBox *boxInput;
    QGridLayout *gridLayoutInput;
    //output
    QComboBox *cmbOutputDevice;
    QComboBox *cmbOutputDeviceSampleRate;
    QComboBox *cmbOutputDeviceChannel;
    QComboBox *cmbOutputDeviceFormat;
//    QLabel *labOutputDevice;
//    QLabel *labOutputDeviceSampleRate;
//    QLabel *labOutputDeviceChannel;
//    QLabel *labOutputDeviceFormat;
    QGroupBox *boxOutput;
    QGridLayout *gridLayoutOutput;

    QVBoxLayout *vLayout;
    QFormLayout *formLayoutInput;
    QFormLayout *formLayoutOutput;
//    QHBoxLayout *hLayoutInput;
//    QHBoxLayout *hLayoutOutput;

    QAudioDevice m_input_device_info;
    QAudioDevice m_output_device_info;

private slots:
    void update_input_audio_device(void);
    void update_output_audio_device(void);
    void input_device_select_changed(int idx);
    void output_device_select_changed(int idx);

signals:
    void input_device_changed(QAudioDevice &input_device);
    void output_device_changed(QAudioDevice &output_device);

};

#endif

